package kotlinx.coroutines.script.analysis


import abc.reflect.App
import android.graphics.Bitmap

import kotlinx.coroutines.script.Block
import kotlinx.coroutines.script.tes.*
import kotlin.math.max

object Analysis {
        fun hit(screenshot: Bitmap, block: Block, hitColors: Set<ColorDiffer>, sp: Int = 1, minPercent: Float, testMark: String? = null): Boolean {
            if (block.left < 0) {
                return false
            } else if (block.right > screenshot.width) {
                return false
            } else if (block.top < 0) {
                return false
            } else if (block.bottom > screenshot.height) {
                return false
            }

            val samplingPx = max(1, sp)
            val total = (block.width / samplingPx + (if (block.width % samplingPx == 0) 0 else 1)) * (block.height / samplingPx + (if (block.height % samplingPx == 0) 0 else 1))
            val hitMin = (total * minPercent).toInt()
            var hitCount = 0
            var x = block.left
            while(x < block.right) {
                var y = block.top
                while(y < block.bottom) {
                    val c = App.take().takePixel(screenshot, x, y)
                    if (hitColors.containsSimilarColor(c)) {
                        hitCount++
                        if (testMark.isNullOrEmpty()) {
                            if (hitCount > hitMin) return true
                        }
                    }
                    y += samplingPx
                }
                x += samplingPx
            }
            if (testMark?.isNotEmpty() == true) printLog { "analysisInfo hit [$testMark] ${hitCount * 1f / total} hitCount $hitCount total $total" }
            return hitCount > hitMin
        }

        fun hitAny(screenshot: Bitmap, block: Block, hitColors: Set<ColorDiffer>, sp: Int = 1, testMark: String? = null): Boolean {
            if (block.left < 0) {
                return false
            } else if (block.right > screenshot.width) {
                return false
            } else if (block.top < 0) {
                return false
            } else if (block.bottom > screenshot.height) {
                return false
            }
            val samplingPx = max(1, sp)
            var x = block.left
            while(x < block.right) {
                var y = block.top
                while(y < block.bottom) {
                    if (hitColors.containsSimilarColor(App.take().takePixel(screenshot, x, y))) {
                        if (testMark?.isNotEmpty() == true) printLog { "analysisInfo hitAny [$testMark] true" }
                        return true
                    }
                    y += samplingPx
                }
                x += samplingPx
            }
            if (testMark?.isNotEmpty() == true) printLog { "analysisInfo hitAny [$testMark] false" }
            return false
        }

        fun hitAnyPoint(screenshot: Bitmap, block: Block, hitColors: Set<ColorDiffer>, sp: Int = 1): Pair<Int, Int>? {
            if (block.left < 0 || block.right > screenshot.width ||
                block.top < 0 || block.bottom > screenshot.height) {
                return null
            }
            val samplingPx = max(1, sp)
            var x = block.left
            while(x < block.right) {
                var y = block.top
                while(y < block.bottom) {
                    if (hitColors.containsSimilarColor(App.take().takePixel(screenshot, x, y))) return Pair(x, y)
                    y += samplingPx
                }
                x += samplingPx
            }
            return null
        }

        fun compareWithLast(new: Bitmap, old: Bitmap?, block: Block, sp: Int, minPercent: Float, offset: Int, testMark: String? = null): Boolean {
            if (old == null) return false
            if (new.width == 0 || new.height == 0 || old.width == 0 || old.height == 0) return false

            val samplingPx = max(1, sp)
            val total = (block.width / samplingPx + (if (block.width % samplingPx == 0) 0 else 1)) * (block.height / samplingPx + (if (block.height % samplingPx == 0) 0 else 1))
            val hitMin = (total * minPercent).toInt()
            var hitCount = 0
            var x = block.left
            while(x < block.right) {
                var y = block.top
                while(y < block.bottom) {
                    val newC = App.take().takePixel(new, x, y)
                    val oldC = App.take().takePixel(old, x, y)
                    if (App.take().isSimilarColor(newC.red, newC.green, newC.blue, oldC.red, oldC.green, oldC.blue, offset, offset, offset)) {
                        hitCount++
                        if (testMark.isNullOrEmpty()) {
                            if (hitCount > hitMin) return true
                        }
                    }
                    y += samplingPx
                }
                x += samplingPx
            }
            if (testMark?.isNotEmpty() == true) printLog { "analysisInfo compareWithLast [$testMark] ${hitCount * 1f / total} hitCount $hitCount total $total" }
            return hitCount > hitMin
        }

        fun compareSkillBitmap(screenshot: Bitmap?, block: Block, target: Bitmap?, sp: Int, minPercent: Float, testMark: String? = null): Boolean {
            if (screenshot == null) return false
            if (target == null) return false
            if (screenshot.width == 0 || screenshot.height == 0 || target.width == 0 || target.height == 0) return false
            val samplingPx = max(1, sp)
            val total = (block.width / samplingPx + (if (block.width % samplingPx == 0) 0 else 1)) * (block.height / samplingPx + (if (block.height % samplingPx == 0) 0 else 1))
            val hitMin = (total * minPercent).toInt()
            var hitCount = 0
            var x = block.left
            while(x < block.right) {
                var y = block.top
                while(y < block.bottom) {
                    val curr = App.take().takePixel(screenshot, x, y)
                    val temp = App.take().takePixel(target, x - block.left, y - block.top)
                    if (App.take().isSimilarColor(curr.red, curr.green, curr.blue,
                            temp.red, temp.green, temp.blue,
                            50, 10, 10)
                    ) {
                        hitCount++
                        if (testMark.isNullOrEmpty()) {
                            if (hitCount > hitMin) return true
                        }
                    }
                    y += samplingPx
                }
                x += samplingPx
            }
            if (testMark?.isNotEmpty() == true) printLog { "analysisInfo hit [$testMark] ${hitCount * 1f / total} hitCount $hitCount total $total" }
            return hitCount > hitMin
        }
}